package com.letv.core.network.volley;

import java.util.concurrent.Executor;

import android.os.Handler;

import com.letv.core.network.volley.VolleyRequest.RequestManner;
import com.letv.core.network.volley.VolleyResponse.CacheResponseState;
import com.letv.core.network.volley.VolleyResponse.NetworkResponseState;
import com.letv.core.network.volley.VolleyResponse.ResponseSupplier;
import com.letv.core.network.volley.listener.ResponseDelivery;

/**
 * 将请求响应进行解析并交付给请求发起者
 * 
 * @author zhuqiao
 * 
 */
public class ExecutorDelivery implements ResponseDelivery {
    private final Executor mResponsePoster;

    public ExecutorDelivery(final Handler handler) {
        mResponsePoster = new Executor() {

            @Override
            public void execute(Runnable command) {
                handler.post(command);
            }
        };
    }

    @Override
    public void postResponse(VolleyRequest<?> request, ResponseSupplier responseSupplier) {
        if (responseSupplier == ResponseSupplier.NETWORK) {
            mResponsePoster.execute(new ResponseDeliveryRunnable(request, responseSupplier,
                    NetworkResponseState.SUCCESS));
        } else {
            mResponsePoster
                    .execute(new ResponseDeliveryRunnable(request, responseSupplier, CacheResponseState.SUCCESS));
        }
    }

    @Override
    public void postError(VolleyRequest<?> request, NetworkResponseState networkState) {
        mResponsePoster.execute(new ResponseDeliveryRunnable(request, ResponseSupplier.NETWORK, networkState));
    }

    @Override
    public void postError(VolleyRequest<?> request, CacheResponseState cacheState) {
        mResponsePoster.execute(new ResponseDeliveryRunnable(request, ResponseSupplier.CACHE, cacheState));
    }

    private class ResponseDeliveryRunnable implements Runnable {
        private final VolleyRequest<?> mRequest;

        private final ResponseSupplier mResponseSupplier;

        private final NetworkResponseState mNetworkState;

        private final CacheResponseState mCacheState;

        public ResponseDeliveryRunnable(VolleyRequest<?> request, ResponseSupplier responseSupplier,
                NetworkResponseState networkState) {
            this(request, responseSupplier, networkState, CacheResponseState.IGNORE);
        }

        public ResponseDeliveryRunnable(VolleyRequest<?> request, ResponseSupplier responseSupplier,
                CacheResponseState cacheState) {
            this(request, responseSupplier, NetworkResponseState.IGNORE, cacheState);
        }

        public ResponseDeliveryRunnable(VolleyRequest<?> request, ResponseSupplier responseSupplier,
                NetworkResponseState networkState, CacheResponseState cacheState) {
            mRequest = request;
            mResponseSupplier = responseSupplier;
            mNetworkState = networkState;
            mCacheState = cacheState;
        }

        @Override
        public void run() {
            if (mRequest == null) {
                return;
            }

            if (mRequest.isCanceled()) {
                // canceled-at-delivery
                mRequest.finish();
                return;
            }

            if (mResponseSupplier == ResponseSupplier.NETWORK) {
                mRequest.deliverNetworkResponse(mNetworkState);
                if (mRequest.shouldPostErrorReport()) {
                    mRequest.deliverErrorReport();
                }
            } else {
                mRequest.deliverCacheResponse(mCacheState);
                if (mRequest.mRequestType == RequestManner.CACHE_THEN_NETROWK) {
                    // 不管成功还是失败，都需要去服务器再获取一遍.(哎，为了保证能够首先从文件缓存中拿到markId，所以做一个同步，回调之后重新设置加上markId的url)
                    mRequest.setRequestType(RequestManner.NETWORK_ONLY);
                    mRequest.add();
                } else if (mRequest.mRequestType == RequestManner.CACHE_FAIL_THEN_NETWORK) {
                    if (mCacheState != CacheResponseState.SUCCESS) {
                        // 缓存请求失败，去服务器上取
                        mRequest.add();
                    } else {
                        mRequest.finish();
                        return;
                    }
                }
            }

            if (shouldFinish()) {
                // done
                mRequest.finish();
            }
        }

        /**
         * 是否需要结束
         * 
         * @return
         */
        private boolean shouldFinish() {
            final RequestManner type = mRequest.mRequestType;

            // 来自网络调度器
            if (mResponseSupplier == ResponseSupplier.NETWORK) {
                return type == RequestManner.CACHE_THEN_NETROWK || type == RequestManner.NETWORK_ONLY
                        || type == RequestManner.CACHE_FAIL_THEN_NETWORK;
            }

            // 来自缓存调度器
            return type == RequestManner.CACHE_ONLY || type == RequestManner.NETWORK_THEN_CACHE;
        }

    }

}
